查看原题请戳这里
因为每条边都只能走一次,所以这道题可以用欧拉路的性质来求解。
我们首先用并查集去记录每一个联通块,然后再统计每一个子图的奇点数,如果是偶数则满足欧拉回路的性质直接ans++ 就好了,如果是奇数,那么需要的蚂蚁数则是奇点数/2
附一下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
   | #include<iostream> #include<cstring> #include<algorithm> #define re register 
  using namespace std;
  int read() {     register int a = 0,f = 1; register char ch;     ch = getchar();     while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();}     while(ch <='9' && ch >='0') {a = a * 10 + ch - 48; ch = getchar();}     return a * f; }
  int n,m,x,y,s,ans,cnt,t,d[100005],fa[100005],use[100005],a[100005],add[100005];
  int find(int p) {     if(fa[p] == p) return p;     return fa[p] = find(fa[p]); }
  void work() {     m = read();     ans = 0;     for(re int i = 1; i <= n; i++) fa[i] = i;     for(re int i = 1; i <= n; i++) d[i] = 0;     for(re int i = 1; i <= n; i++) a[i] = 0;     for(re int i = 1; i <= n; i++) add[i] = 0;     for(re int i = 1; i <= m; i++)     {         x = read(); y = read();         d[x] ++; d[y] ++;         if(find(x) != find(y))          fa[find(y)] = find(x);     }     for(int i = 1; i<= n; i++)     {         a[find(i)]++;          if(d[i] % 2 == 1) add[find(i)] ++;     }              for(int i = 1; i <= n; i++)     {         if(a[i] <= 1) continue;           else if(add[i] == 0) ans += 1;         else if(add[i] > 0) ans += add[i]/2;     }     cout << ans << endl; } int main() {     while(cin >> n)    work();     return 0; }
   |